package com.kavin.design.decorate;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * @author kavin
 * @Description 测试装饰模式 ---> 动态地为对象增加新的功能或者撤销功能（继承就不能做到这一点）
 * @create 2020/6/28
 *  创建一个新类 （PhoneDecorate）
 *  在类中创建需要扩展的类或者其父类的对象引用 （ private Phone phone;）
 *  将所需要扩展类或者其父类对象通过构造器传入对象的引用中。（MusicPhoneDecorate 和 RingPhoneDecorate 的构造器）
 *  对需要扩展类的功能进行覆盖 （call方法）
 *
 **/
public class phoneDemo {

    public static void main(String[] args) {
        System.out.println("============未装饰之前===================");
        Phone phone = new Iphone();
        phone.call();
        System.out.println("================装饰彩铃=================");
        Phone ring = new RingPhoneDecorate(phone);
        ring.call();
        System.out.println("================装饰音乐=================");
        Phone music = new MusicPhoneDecorate(phone);
        music.call();
        System.out.println("================装饰彩铃和音乐=================");
        /**
         *  执行过程: 子类的构造方法为父类的成员变量Phone赋值具体对象，子类的call（）方法添加自己的逻辑。在调用父类call方法逻辑。
         *  (1)RingPhoneDecorate.call();
         *  (2)RingPhoneDecorate.call() 又调用了super.call(),而RingPhoneDecorate的构造方法给父类的Phone成员变量赋值为MusicPhoneDecorate。
         *  (3)super.call()调用了PhoneDecorate.call()方法。this.phone.call();由于上面给phone赋值为MusicPhoneDecorate。所以这里又调用了MusicPhoneDecorate.call()方法。
         *  (4)MusicPhoneDecorate.call().又调用了super.call(),而MusicPhoneDecorate的构造方法给父类的Phone成员变量赋值为Iphone。
         *  (5)super.call()调用了PhoneDecorate.call()方法。this.phone.call();由于上面给phone赋值为Iphone。所以这里又调用了Iphone.call()方法。
         *  (6)RingPhoneDecorate.call() --->MusicPhoneDecorate.call() --->Iphone.call
        */

        PhoneDecorate ringAndMusic = new RingPhoneDecorate(new MusicPhoneDecorate(phone));
        ringAndMusic.call();

       //想想我们在IO流中的使用，字节流被包装成字符流，字符流被包装成缓冲流.这里就是利用了装饰者模式
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));


    }

}
